package org.shangda.wechat.pet.util;

import org.shangda.wechat.pet.error.BussinessException;
import lombok.extern.slf4j.Slf4j;
import org.apache.tika.Tika;
import org.apache.tika.mime.MimeType;
import org.apache.tika.mime.MimeTypes;


import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.net.URL;

@Slf4j
public class FileUtil {
    public static void uploadFile(byte[] file, String filePath, String fileName) {
        log.info("file size: {}", file.length);
        File targetFile = new File(filePath);
        if(!targetFile.exists()){
            targetFile.mkdirs();
        }

        log.info("fileUtil filePath+fileName = {}", filePath+fileName);
        try(FileOutputStream out = new FileOutputStream(filePath+fileName)) {
            out.write(file);
            out.flush();
            out.getFD().sync();
        }catch (Exception e){
            log.error("uploadFile exception:", e);
            throw new RuntimeException("uploadFile exception");
        }
    }

    /**
     * 获取文件的后缀名
     * @param file
     * @return
     */
    public static String getFileExt(File file){
        try {
            Tika tika = new Tika();
            String contentType = tika.detect(file);
            MimeTypes allTypes = MimeTypes.getDefaultMimeTypes();
            MimeType mimeType = allTypes.forName(contentType);
            String ext = mimeType.getExtension();
            return ext;
        } catch (Exception e) {
            log.error("getFileExt exception:", e);
            throw new BussinessException("解析文件后缀异常");
        }
    }

    /**
     * 获取文件的后缀名
     * @param url
     * @return
     */
    public static String getFileExt(String url){
        try {
            Tika tika = new Tika();
            String contentType = tika.detect(new URL(url));
            MimeTypes allTypes = MimeTypes.getDefaultMimeTypes();
            MimeType mimeType = allTypes.forName(contentType);
            String ext = mimeType.getExtension();
            return ext;
        } catch (Exception e) {
            log.error("getFileExt exception:", e);
            throw new BussinessException("解析文件后缀异常");
        }
    }

    /**
     * 获取文件的后缀名
     * @param data
     * @return
     */
    public static String getFileExt(byte[] data){
        try {
            Tika tika = new Tika();
            String contentType = tika.detect(data);
            MimeTypes allTypes = MimeTypes.getDefaultMimeTypes();
            MimeType mimeType = allTypes.forName(contentType);
            String ext = mimeType.getExtension();
            return ext;
        } catch (Exception e) {
            log.error("getFileExt exception:", e);
            throw new BussinessException("解析文件后缀异常");
        }
    }

    /**
     * 获得Amr语音长度，单位秒
     * @param file
     * @return
     * @throws IOException
     */
    public static long getAmrDuration(File file) {
        long duration = -1;
        int[] packedSize = { 12, 13, 15, 17, 19, 20, 26, 31, 5, 0, 0, 0, 0, 0, 0, 0 };
        try(RandomAccessFile randomAccessFile = new RandomAccessFile(file, "rw")) {
            long length = file.length();//文件的长度
            int pos = 6;//设置初始位置
            int frameCount = 0;//初始帧数
            int packedPos = -1;
            byte[] datas = new byte[1];//初始数据值
            while (pos <= length) {
                randomAccessFile.seek(pos);
                if (randomAccessFile.read(datas, 0, 1) != 1) {
                    duration = length > 0 ? ((length - 6) / 650) : 0;
                    break;
                }
                packedPos = (datas[0] >> 3) & 0x0F;
                pos += packedSize[packedPos] + 1;
                frameCount++;
            }
            duration += frameCount * 20;//帧数*20
            return duration / 1000;
        }catch (Exception e){
            log.error("getAmrDuration exception:", e);
        }
        return 0L;
    }

    /**
     * 获取wav格式音频时长，单位秒
     * @param wavFile
     * @return
     * @throws Exception
     */
    public static long getWavDuration4File(File wavFile){
        Clip clip = null;
        try {
            clip = AudioSystem.getClip();
            AudioInputStream ais = AudioSystem.getAudioInputStream(wavFile);
            clip.open(ais);
            long time = clip.getMicrosecondLength()/1000/1000;
            return time;
        } catch (Exception e) {
            log.error("getWavDuration4Url exception", e);
        }finally {
            clip.close();
        }
        return 0L;
    }

    /**
     * 获取wav格式音频时长，单位秒
     * @param wavUrl
     * @return
     * @throws Exception
     */
    public static long getWavDuration4Url(URL wavUrl) throws Exception {
        Clip clip = null;
        try {
            clip = AudioSystem.getClip();
            AudioInputStream ais = AudioSystem.getAudioInputStream(wavUrl);
            clip.open(ais);
            long time = clip.getMicrosecondLength()/1000/1000;
            return time;
        } catch (Exception e) {
            log.error("getWavDuration4Url exception", e);
        }finally {
            clip.close();
        }
        return 0L;
    }



    public static void main(String[] args) throws Exception{
//        File file = new File("/Users/shengzhu/Downloads/1590551903533.mp4");
//        File file = new File("/Users/shengzhu/Music/虾米音乐/刘允乐-太早.mp3");
//        System.out.println(file.exists());
//        System.out.println(getMp3Duration(file));
        /*String ext = ".amr";
        ext = ext.replaceAll("\\.","");
        System.out.println(ext);*/

        /*File file = new File("/Users/shengzhu/fsdownload/e28a3bb2443542a39ca412e66b1cccde.mp3");
        System.out.println(getFileExt(file));*/
        File source = new File("/Users/shengzhu/Downloads/2a9668dbd6894400b649e118cdf4f588.amr");
        File target = new File("/Users/shengzhu/Downloads/2a9668dbd6894400b649e118cdf4f588.mp3");

//        AudioUtils.amrToMp3(source, target);

//        encoder.encode(source, target, attrs);
        System.out.println(getFileExt(target));
        System.out.println(getAmrDuration(target));
    }
}
